
/**
 * Copyright 2009 cestum.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.waveprotocol.wave.model.id {
import flash.utils.ByteArray;

import org.waveprotocol.wave.model.util.Constants;

/**
 * This class is used to generate URI for ids.
 **/
public class IdURIEncoderDecoder {
	
	/** Used to encode parts of URI that needs to be escaped */
	private var encoder:URIEncoderDecoder;
	
	/**
	 * @param percentEncoder An encoder able to percent encode strings.
	 */
	public function IdURIEncoderDecoder(percentEncoder:PercentEncoderDecoder) {
		this.encoder = new URIEncoderDecoder(percentEncoder);
	}
	
	public function waveletNameToURI(name:WaveletName):ByteArray {
		var value:String =
			IdConstants.WAVE_URI_SCHEME + "://" +  waveletNameToURIPath(name);
		var byte:ByteArray  = new ByteArray();
		byte.writeMultiByte(value,"UTF-8");
		return byte;
	}
	public function waveletNameToURIPath(name:WaveletName):String {
		var waveId:WaveId= name.waveId;
		var waveletId:WaveletId= name.waveletId;
		var waveDomain:String= waveId.getDomain();
		
		if (waveletId.getDomain() == (waveDomain)) {
			waveDomain = "";
		} else {
			waveDomain += "!";
		}
		
		return waveletId.getDomain() + "/" + waveDomain + waveId.getId() +
			"/" + waveletId.getId();
	}
	
	public function uriToWaveletName(serialisedForm:String):WaveletName {
		var prefix:String= IdConstants.WAVE_URI_SCHEME + "://";
		if (!serialisedForm.indexOf(prefix) == 0) {
			throw new Error("Invalid scheme for the wavelet name URI: " +
				serialisedForm);
		}
		return uriPathToWaveletName(serialisedForm.substring(prefix.length));
	}
	
	public function uriPathToWaveletName(serialisedForm:String):WaveletName {
		var parts:Array= serialisedForm.split("/");
		if (parts.length != 3) {
			throw new Error("Wavelet name URI path expected in the format of" +
				" <wavelet domain>/[<wave domain>!]<wave id>/<wavelet id> but got: " +
				serialisedForm);
		}
		var waveletId:WaveletId= new WaveletId(parts[0], parts[2]);
		var waveIdParts:Array= Constants.DEFAULT_ESCAPER.splitWithoutUnescaping(
			'!', parts[1]);
		var waveId:WaveId;
		if (waveIdParts.length == 1) {
			waveId = new WaveId(waveletId.getDomain(), encoder.decode(waveIdParts[0]));
		} else if (waveIdParts.length == 2) {
			waveId = new WaveId(waveIdParts[0], waveIdParts[1]);
		} else {
			throw new Error("Wave id in URI path is invalid. Expected the format" +
				" [<wave domain>!]<wave id> but got: " + parts[1]);
		}
		
		return WaveletName.of(waveId, waveletId);
	}
}
}